package utils

import (
	"archive/zip"
	"fmt"
	"io"
	"os"
	"strings"
)

type DocxEditor struct {
	files    map[string][]byte
	document []byte
}

// 打开 DOCX 文件
func NewDocxEditor(filename string) (*DocxEditor, error) {
	reader, err := zip.OpenReader(filename)
	if err != nil {
		return nil, fmt.Errorf("无法打开文件: %w", err)
	}
	defer reader.Close()

	editor := &DocxEditor{
		files: make(map[string][]byte),
	}

	// 读取所有文件
	for _, file := range reader.File {
		fileReader, err := file.Open()
		if err != nil {
			return nil, err
		}

		content, err := io.ReadAll(fileReader)
		fileReader.Close()
		if err != nil {
			return nil, err
		}

		editor.files[file.Name] = content

		if file.Name == "word/document.xml" {
			editor.document = content
		}
	}

	return editor, nil
}

// 1. 替换指定文本
func (d *DocxEditor) ReplaceText(oldText, newText string) error {
	if d.document == nil {
		return fmt.Errorf("文档内容为空")
	}

	content := string(d.document)

	// 在 XML 中安全替换文本（只在 <w:t> 标签内替换）
	newContent := d.replaceInTextTags(content, oldText, newText)

	d.document = []byte(newContent)
	d.files["word/document.xml"] = d.document

	return nil
}

// 在 <w:t> 标签内安全替换文本
func (d *DocxEditor) replaceInTextTags(xmlContent, oldText, newText string) string {
	var result strings.Builder
	content := xmlContent

	for {
		// 查找 <w:t> 标签开始
		start := strings.Index(content, "<w:t")
		if start == -1 {
			result.WriteString(content)
			break
		}

		// 写入标签之前的内容
		result.WriteString(content[:start])

		// 找到标签结束
		tagEnd := strings.Index(content[start:], ">")
		if tagEnd == -1 {
			result.WriteString(content[start:])
			break
		}
		tagEnd += start

		// 找到文本结束标签
		textEnd := strings.Index(content[tagEnd:], "</w:t>")
		if textEnd == -1 {
			result.WriteString(content[start:])
			break
		}
		textEnd += tagEnd

		// 提取文本内容
		textStart := tagEnd + 1
		textContent := content[textStart:textEnd]

		// 替换文本
		newTextContent := strings.ReplaceAll(textContent, oldText, newText)

		// 写入标签和替换后的文本
		result.WriteString(content[start:textStart])
		result.WriteString(newTextContent)
		result.WriteString("</w:t>")

		// 继续处理剩余内容
		content = content[textEnd+7:]
	}

	return result.String()
}

// 2. 搜索并插入表格
func (d *DocxEditor) InsertTableAt(searchText string, headers []string, data [][]string) error {
	if d.document == nil {
		return fmt.Errorf("文档内容为空")
	}

	content := string(d.document)

	// 查找搜索文本的位置
	pos := strings.Index(content, searchText)
	if pos == -1 {
		return fmt.Errorf("未找到文本: %s", searchText)
	}

	// 生成表格 XML
	tableXML := d.generateTableXML(headers, data)

	// 在找到的位置插入表格
	newContent := content[:pos] + tableXML + content[pos:]

	d.document = []byte(newContent)
	d.files["word/document.xml"] = d.document

	return nil
}

// 生成表格 XML
func (d *DocxEditor) generateTableXML(headers []string, data [][]string) string {
	var table strings.Builder

	// 表格开始
	table.WriteString(`<w:tbl><w:tblPr><w:tblW w:w="0" w:type="auto"/><w:tblBorders>`)
	table.WriteString(`<w:top w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
	table.WriteString(`<w:left w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
	table.WriteString(`<w:bottom w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
	table.WriteString(`<w:right w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
	table.WriteString(`</w:tblBorders></w:tblPr>`)

	// 表头行
	table.WriteString(`<w:tr><w:trPr><w:tblHeader/></w:trPr>`)
	for _, header := range headers {
		table.WriteString(`<w:tc><w:tcPr><w:tcW w:w="2000" w:type="dxa"/></w:tcPr>`)
		table.WriteString(`<w:p><w:r><w:rPr><w:b/></w:rPr><w:t>`)
		table.WriteString(header)
		table.WriteString(`</w:t></w:r></w:p></w:tc>`)
	}
	table.WriteString(`</w:tr>`)

	// 数据行
	for _, row := range data {
		table.WriteString(`<w:tr>`)
		for _, cell := range row {
			table.WriteString(`<w:tc><w:tcPr><w:tcW w:w="2000" w:type="dxa"/></w:tcPr>`)
			table.WriteString(`<w:p><w:r><w:t>`)
			table.WriteString(cell)
			table.WriteString(`</w:t></w:r></w:p></w:tc>`)
		}
		table.WriteString(`</w:tr>`)
	}

	// 表格结束
	table.WriteString(`</w:tbl>`)

	// 添加换行段落
	table.WriteString(`<w:p><w:r><w:br/></w:r></w:p>`)

	return table.String()
}

// 保存修改后的文档
func (d *DocxEditor) Save(filename string) error {
	// 创建新文件
	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	zipWriter := zip.NewWriter(file)
	defer zipWriter.Close()

	// 写入所有文件
	for name, content := range d.files {
		writer, err := zipWriter.Create(name)
		if err != nil {
			return err
		}

		_, err = writer.Write(content)
		if err != nil {
			return err
		}
	}

	return nil
}

// 获取文档内容（用于调试）
func (d *DocxEditor) GetTextContent() string {
	if d.document == nil {
		return ""
	}
	return d.extractTextFromXML(string(d.document))
}

// 从 XML 提取文本内容
func (d *DocxEditor) extractTextFromXML(xmlContent string) string {
	var result strings.Builder
	content := xmlContent

	for {
		start := strings.Index(content, "<w:t")
		if start == -1 {
			break
		}

		tagEnd := strings.Index(content[start:], ">")
		if tagEnd == -1 {
			break
		}
		textStart := start + tagEnd + 1

		textEnd := strings.Index(content[textStart:], "</w:t>")
		if textEnd == -1 {
			break
		}
		textEnd += textStart

		text := content[textStart:textEnd]
		result.WriteString(text)
		result.WriteString(" ")

		content = content[textEnd+7:]
	}

	return strings.TrimSpace(result.String())
}

// 在 DocxEditor 结构体中添加以下方法

// 批量替换多个文本
func (d *DocxEditor) ReplaceMultiple(replacements map[string]string) error {
	for old, new := range replacements {
		if err := d.ReplaceText(old, new); err != nil {
			return fmt.Errorf("替换 %s 失败: %w", old, err)
		}
	}
	return nil
}

// 在指定段落后插入表格
func (d *DocxEditor) InsertTableAfterParagraph(paragraphText string, headers []string, data [][]string) error {
	content := string(d.document)

	// 查找段落位置
	pos := strings.Index(content, paragraphText)
	if pos == -1 {
		return fmt.Errorf("未找到段落: %s", paragraphText)
	}

	// 找到段落结束位置
	paragraphEnd := strings.Index(content[pos:], "</w:p>")
	if paragraphEnd == -1 {
		return fmt.Errorf("未找到段落结束标签")
	}
	insertPos := pos + paragraphEnd + 6 // 6 是 </w:p> 的长度

	tableXML := d.generateTableXML(headers, data)
	newContent := content[:insertPos] + tableXML + content[insertPos:]

	d.document = []byte(newContent)
	d.files["word/document.xml"] = d.document

	return nil
}

// 插入带样式的表格
func (d *DocxEditor) GenerateStyledTable(headers []string, data [][]string, style TableStyle) string {
	var table strings.Builder

	// 根据样式设置表格属性
	table.WriteString(`<w:tbl><w:tblPr>`)
	table.WriteString(`<w:tblW w:w="0" w:type="auto"/>`)

	// 边框样式
	if style.Border {
		table.WriteString(`<w:tblBorders>`)
		table.WriteString(`<w:top w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
		table.WriteString(`<w:left w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
		table.WriteString(`<w:bottom w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
		table.WriteString(`<w:right w:val="single" w:sz="4" w:space="0" w:color="000000"/>`)
		table.WriteString(`</w:tblBorders>`)
	}

	table.WriteString(`</w:tblPr>`)

	// 生成表格内容...
	return table.String()
}

type TableStyle struct {
	Border   bool
	HeaderBg string
	Zebra    bool
}
